﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using DesignPatterns.AbstractFactoryPattern.Classes;
using DesignPatterns.AbstractFactoryPattern.Factories;
using DesignPatterns.FactoryPattern.Classes;
using DesignPatterns.FactoryPattern.Factories;
using DesignPatterns.BuilderPattern;
using DesignPatterns.PrototypePattern;
using DesignPatterns.SingletonPattern;
using DesignPatterns.AdapterPattern;
using DesignPatterns.BridgePattern;
using DesignPatterns.CompositePattern;
using DesignPatterns.DecoratorPattern;
using DesignPatterns.FacadePattern;
using DesignPatterns.FlyweightPattern;
using DesignPatterns.ProxyPattern;
using DesignPatterns.ChainOfResponsibilityPattern;
using DesignPatterns.CommandPattern;
using DesignPatterns.InterpreterPattern;
using DesignPatterns.MediatorPattern;
using DesignPatterns.MementoPattern;
using DesignPatterns.ObserverPattern;
using DesignPatterns.StatePattern;
using DesignPatterns.StrategyPattern;
using DesignPatterns.TemplateMethodPattern;
using DesignPatterns.VisitorPattern;

namespace DesignPatterns
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CarFactory audiFactory = new AudiFactory(); 
            Driver driver1 = new Driver(audiFactory); 
            driver1.CompareSpeed();

            CarFactory mercedesFactory = new MercedesFactory(); 
            Driver driver2 = new Driver(mercedesFactory); 
            driver2.CompareSpeed();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            IVehicle[] vehicles = new IVehicle[3];
            VehicleFactory factory = new VehicleFactory();
            vehicles[0] = factory.GetVehicle("Car");
            vehicles[1] = factory.GetVehicle("Bus");
            vehicles[2] = factory.GetVehicle("Motorbike");

            vehicles[0].Drive(5);
            vehicles[1].Drive(10);
            vehicles[2].Drive(20);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            VehicleDirector director = new VehicleDirector();
            Vehicle sportscar = director.BuildVehicle(new SportsCarManufacturer());
            sportscar.Show();

            Vehicle familycar = director.BuildVehicle(new FamilyCarManufacturer());
            familycar.Show();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Developer d1 = new Developer();
            d1.Language = "C#";
            d1.Name = "Henry";
            d1.Department = "IT";
            Console.WriteLine(d1.GetDetails());

            Developer d2 = (Developer)d1.Clone();
            d2.Name = "Mark";
            Console.WriteLine(d2.GetDetails());

            Analyst a1 = new Analyst();            
            a1.Name = "Jack";
            a1.Department = "Business Services";
            Console.WriteLine(a1.GetDetails());

            Analyst a2 = (Analyst)a1.Clone();
            a2.Name = "Luke";
            Console.WriteLine(a2.GetDetails());
        }

        private void button5_Click(object sender, EventArgs e)
        {
            Singleton s1 = Singleton.Instance;
            Console.WriteLine(s1.Title);

            Singleton s2 = Singleton.Instance;
            Console.WriteLine(s2.Title);

        }

        private void button8_Click(object sender, EventArgs e)
        {
            Compound water = new RichCompound("Water");
            water.Display();

            Compound benzene = new RichCompound("Benzene");
            benzene.Display();

            Compound ethanol = new RichCompound("Ethanol");
            ethanol.Display();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            SmartTV myTv = new SmartTV();

            Console.WriteLine("Select A source to get TV Guide and Play");
            Console.WriteLine("1. Local Cable TV\n2. Local Dish TV\n3. IP TV");

            String value = Interaction.InputBox("1. Local Cable TV\n2. Local Dish TV\n3. IP TV", "Select TV Type");

            // Let us see what user has selected and select the video source accordingly
            switch (value)
            {
                case "1":
                    myTv.VideoSource = new LocalCableTV();
                    break;

                case "2":
                    myTv.VideoSource = new LocalDishTV();
                    break;

                case "3":
                    myTv.VideoSource = new IPTVService();
                    break;
            }

            Console.WriteLine(); //some whitespace on output for readability

            //Let us show the TV guide from selected source
            myTv.ShowTvGuide();

            //Let us now play the selected TV source.
            myTv.PlayTV();

            Console.WriteLine(); 
        }

        private void button7_Click(object sender, EventArgs e)
        {
            CompositeElement root =  new CompositeElement("Picture");
            root.Add(new PrimitiveElement("Red Line"));
            root.Add(new PrimitiveElement("Blue Circle"));
            root.Add(new PrimitiveElement("Green Box"));

            // Create a branch
            CompositeElement comp = new CompositeElement("Two Circles");
            comp.Add(new PrimitiveElement("Black Circle"));
            comp.Add(new PrimitiveElement("White Circle"));
            root.Add(comp);            

            // Add and remove a PrimitiveElement
            PrimitiveElement pe =  new PrimitiveElement("Yellow Line");
            root.Add(pe);
            root.Remove(pe);

            // Recursively display nodes
            root.Display(1);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            ProductBase BB = new Product();
            BB = new ProductDelivery(BB);
            BB = new ProductVAT(BB);
            Console.WriteLine("Total Price = " + BB.Cost().ToString());
        }

        private void button10_Click(object sender, EventArgs e)
        {
            Mortgage mortgage = new Mortgage();

            // Evaluate mortgage eligibility for customer
            BankCustomer customer = new BankCustomer("Ann McKinsey");

            bool eligible = mortgage.IsEligible(customer, 125000);

            Console.WriteLine("\n" + customer.Name + " has been " + (eligible ? "Approved" : "Rejected"));

        }

        private void button11_Click(object sender, EventArgs e)
        {
            AlienFactory factory = new AlienFactory();
            factory.SaveAlien(new LargeAlien());
            factory.SaveAlien(new LittleAlien());

            //now access the flyweight objects
            IAlien a = factory.GetAlien(0);
            IAlien b = factory.GetAlien(1);

            //show intrinsic states, all accessed in memory without calculations
            Console.WriteLine("Showing intrinsic states...");
            Console.WriteLine("Alien of type 0 is " + a.Shape);
            Console.WriteLine("Alien of type 1 is " + b.Shape);

            //show extrinsic states, need calculations
            Console.WriteLine("Showing extrinsic states...");
            Console.WriteLine("Alien of type 0 is " + a.GetColor(0).ToString());
            Console.WriteLine("Alien of type 1 is " + b.GetColor(1).ToString());
        }

        private void button12_Click(object sender, EventArgs e)
        {
            MathsProxy proxy = new MathsProxy();

            // Do the maths
            Console.WriteLine("4 + 2 = " + proxy.Add(4, 2));
            Console.WriteLine("4 - 2 = " + proxy.Sub(4, 2));
            Console.WriteLine("4 * 2 = " + proxy.Mul(4, 2));
            Console.WriteLine("4 / 2 = " + proxy.Div(4, 2));
        }

        private void button19_Click(object sender, EventArgs e)
        {
            Approver larry = new Director();
            Approver sam = new VicePresident();
            Approver tammy = new President();

            larry.SetSuccessor(sam);
            sam.SetSuccessor(tammy);

            // Generate and process purchase requests
            Purchase p = new Purchase(2034, 350.00, "Assets");
            larry.ProcessRequest(p);

            p = new Purchase(2035, 32590.10, "Project X");
            larry.ProcessRequest(p);

            p = new Purchase(2036, 122100.00, "Project Y");
            larry.ProcessRequest(p);
        }

        private void button13_Click(object sender, EventArgs e)
        {
            CalcUser user = new CalcUser();
            
            // User presses calculator buttons
            user.Compute('+', 100);
            user.Compute('-', 50);
            user.Compute('*', 10);
            user.Compute('/', 2);

            // Undo 4 commands
            user.Undo(4);

            // Redo 3 commands
            user.Redo(3);
        }

        private void button14_Click(object sender, EventArgs e)
        {
            string roman = "MCMXXVIII";

            Context context = new Context(roman);

            // Build the 'parse tree'
            List<Expression> tree = new List<Expression>();
            tree.Add(new ThousandExpression());
            tree.Add(new HundredExpression());
            tree.Add(new TenExpression());
            tree.Add(new OneExpression());

            // Interpret
            foreach (Expression exp in tree)
            {
                exp.Interpret(context);
            }

            Console.WriteLine("{0} = {1}", roman, context.Output);

        }

        private void button15_Click(object sender, EventArgs e)
        {
            Chatroom chatroom = new Chatroom();

            // Create participants and register them
            Participant George = new Beatle("George");
            Participant Paul = new Beatle("Paul");
            Participant Ringo = new Beatle("Ringo");
            Participant John = new Beatle("John");
            Participant Yoko = new NonBeatle("Yoko");

            chatroom.Register(George);
            chatroom.Register(Paul);
            chatroom.Register(Ringo);
            chatroom.Register(John);
            chatroom.Register(Yoko);
            
            // Chatting participants
            Yoko.Send("John", "Hi John!");
            Paul.Send("Ringo", "All you need is love");
            Ringo.Send("George", "My sweet Lord");
            Paul.Send("John", "Can't buy me love");
            John.Send("Yoko", "My sweet love");
        }

        private void button16_Click(object sender, EventArgs e)
        {
            SalesProspect s = new SalesProspect();
            s.Name = "Noel van Halen";
            s.Phone = "(412) 256-0990";
            s.Budget = 25000.0;

            // Store internal state
            ProspectMemory m = new ProspectMemory();
            m.Memento = s.SaveMemento();

            // Continue changing originator
            s.Name = "Leo Welch";
            s.Phone = "(310) 209-7111";
            s.Budget = 1000000.0;

            // Restore saved state
            s.RestoreMemento(m.Memento);
        }

        private void button17_Click(object sender, EventArgs e)
        {
            IBM ibm = new IBM("IBM", 120.00);
            ibm.Attach(new Investor("Sorros"));
            ibm.Attach(new Investor("Berkshire"));

            // Fluctuating prices will notify investors
            ibm.Price = 120.10;
            ibm.Price = 121.00;
            ibm.Price = 120.50;
            ibm.Price = 120.75;
        }

        private void button18_Click(object sender, EventArgs e)
        {
            Account account = new Account("Jim Johnson");

            // Apply financial transactions
            account.Deposit(500.0);
            account.Deposit(300.0);
            account.Deposit(550.0);
            account.PayInterest();
            account.Withdraw(2000.00);
            account.Withdraw(1100.00);
        }

        private void button20_Click(object sender, EventArgs e)
        {
            SortedList studentRecords = new SortedList();
            studentRecords.Add("Samual");
            studentRecords.Add("Jimmy");
            studentRecords.Add("Sandra");
            studentRecords.Add("Vivek");
            studentRecords.Add("Anna");

            studentRecords.SetSortStrategy(new QuickSort());
            studentRecords.Sort();
            
            studentRecords.SetSortStrategy(new ShellSort());
            studentRecords.Sort();
            
            studentRecords.SetSortStrategy(new MergeSort());
            studentRecords.Sort();

        }

        private void button21_Click(object sender, EventArgs e)
        {
            DataAccessObject daoCategories = new Categories();
            daoCategories.Run();

            DataAccessObject daoProducts = new Products();
            daoProducts.Run();
        }

        private void button22_Click(object sender, EventArgs e)
        {
            Employees emp = new Employees();
            emp.Attach(new Clerk());
            emp.Attach(new CompanyDirector());
            emp.Attach(new CompanyPresident());

            // Employees are 'visited'
            emp.Accept(new IncomeVisitor());
            emp.Accept(new VacationVisitor());
        }
    }
}
    